#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include<ctype.h>
#define MAX 100
#define num_blocos 24197//lSize divisel por 37, 61, 24197//Quanto maior o divisor mais rapido a execução será

int palindromo(char *string);
char arruma(char letra);
void primo(char palindromo[]);
void crivo();

int contador_primo = 0;
int intervalo[10000];

int main() {
    FILE * pFile, *fp;
    long lSize;
    char * buffer[num_blocos];
    size_t result;
    int i = 0, j = 0, k = 0, contador_palindromo = 0;
    clock_t inicio = 0, fim = 0;
    inicio = clock();

    pFile = fopen ( "wikipedia.txt" , "rb" );
    if (pFile==NULL) {fputs ("File error",stderr); exit (1);}

    fp = fopen("maior.txt","w+");
    // obtain file size:
    fseek (pFile , 0 , SEEK_END);
    lSize = ftell (pFile);//lSize = 54612629
    int TAM = lSize/num_blocos;
    rewind (pFile);

    for(i = 0; i < num_blocos; i++){
        buffer[i] = (char*) malloc (sizeof(char)*TAM);
    }

// copia para o buffer
    for(i = 0; i < num_blocos; i++){
        result = fread (buffer[i],1,TAM,pFile);
        if (result != TAM) {
            fputs ("Reading error",stderr);
            exit (3);
        }
    }
  /* the whole file is now loaded in the memory buffer. */

    char palavra[100000];

	crivo();

    for(k = 0; k < num_blocos; k++){
        while(i < strlen(buffer[k])) {
            while(isalpha(buffer[k][i])) {
                palavra[j] = buffer[k][i];
                j++;
                i++;
            }
            palavra[j] = '\0';
            j = 0;
            if(palindromo(palavra) == 0) {
                contador_palindromo++;
                primo(palavra);
            }
            i++;
        }
        i = 0;
    }
    fprintf(fp,"O arquivo tem %d palindromos\ne %d palindromos primos\n", contador_palindromo, contador_primo);

    fclose (pFile);
    for(i = 0; i < num_blocos; i++){
        free (buffer[i]);
    }

    fim  = clock();
    //tempo de execução
    double  tempo = (fim - inicio)/(CLOCKS_PER_SEC/1000);
    fprintf(fp,"\ntempo = %g", tempo);
    fclose(fp);

    return 0;
}

int palindromo(char *string) {

    char str1[MAX];
    int tam, i, j;

    if(strlen(string) > 1){
        for(i=0;i<strlen(string);i++) {
            string[i] = arruma(string[i]);
        }

        tam = strlen(string);

        for (i=tam-1,j=0;i>=0;i--,j++){
            str1[j] = string[i];
            if(str1[j] != string[j])//Verifica se a primeira letra é diferente da ultima, se for não é palindromo, se não for continua comparando até o fim da palavra.
                return 1;
        }

        str1[tam] = '\0';
        return 0;
    }
    else
        return 1;
}

char arruma(char letra) {
    if(letra >= 65 && letra <= 90)
        letra = letra + 32;

    return letra;
}

void primo(char palindromo[]) {
    int i, l;
    int tam = strlen(palindromo), soma = 0;
         //int intervalo[10000];

     //printf("\nA palavra %s e um palindromo\n", palindromo);

    for(i = 0; i < tam; i++) {
        soma += palindromo[i];
    }

    for(l = 0; l < 10000; l++) {
        if(intervalo[l] != -1) {
        //printf(" %d ", intervalo[l]);
            if(intervalo[l] == soma){
                contador_primo++;
                //printf("\n%dA soma das letras de %s e %d e e primo\n", contador_primo,palindromo, soma);
            }
        }
    }
    //printf("\n");
}

void crivo() {
    int i, j, k;
    int limite, div = 0;

     for(i = 0; i < 10000; i++) {
        intervalo[i] = i + 1;
     }

     limite = sqrt(10000);

     for(i = 0; i < 10000; i++) {
            if(intervalo[i] > 1) {
                for (j = 1; j <= intervalo[i]; j++) {
                    if (intervalo[i] % j == 0) {
                        div++;
                    }
                }
                if(div == 2) { //se e primo
                    for(k = i+1; k < 10000; k++) {
                        if(intervalo[k] % intervalo[i] == 0) {
                          //remover da lista
                            intervalo[k] = -1;
                        }
                    }
                }
                else {
                    intervalo[i] = -1;
                }
                div = 0;
                if(intervalo[i] == limite) {
                    break;
                }
            }
            else {
                intervalo[i] = -1;
            }
        }
}
